<?php
namespace Easy;

use Easy\Exception\LogicError;

class Router
{
    private static $_clsHash     = [];
    private static $_clsUriHash  = [];

    public static function setClsHash($clsHash)
    {
        self::$_clsHash = $clsHash;
    }

    public static function getClsHash()
    {
        return self::$_clsHash;
    }

    public static function setClsUriHash($uriHash)
    {
        self::$_clsUriHash = $uriHash;
    }

    public static function getClsUriHash()
    {
        return self::$_clsUriHash;
    }

    private static function getRouterUri()
    {
        $uri        = $_SERVER['REQUEST_URI'];
        $uri = str_replace('?'.$_SERVER['QUERY_STRING'],'',$uri);
        $urlListArr = self::getClsUriHash();
        $reqUri     = $uri;
        if (!isset($urlListArr[$uri]) && substr($uri, -1, 1) != '/') {
            foreach ($urlListArr as $k => $v) {
                if (strpos($uri, $k) === 0) {
                    $reqUri = $k;
                    break;
                }
            }
            $requestData = str_replace($reqUri . '/', '', $uri);
            $requestData = explode('/', $requestData);
            $reqUri .= '/' . array_shift($requestData);
            foreach ($requestData as $k => $v) {
                if ($k % 2 !== 0 || !isset($requestData[$k + 1])) {
                    continue;
                }
                $_GET[$v] = $requestData[$k + 1];
            }
        }

        return explode('/', $reqUri);
    }

    public static function dispatchByFullness()
    {
        $uriArr = self::getRouterUri();
        $method = array_pop($uriArr);
        if (!$method) {
            throw new LogicError('method can not empty');
        }
        $url    = implode('/', $uriArr);
        $urlCls = self::getClsUriHash();
        if (!isset($urlCls[$url])) {
            throw new LogicError('can not find ' . $url . '\'s cls ');
        }
        $class = $urlCls[$url];
        if (!method_exists($class, $method)) {
            throw new LogicError($class . '\'s method not found ');
        }
        self::defineSysConst($class, $method);

        return ['class' => $class, 'method' => $method];
    }

    public static function dispatchByNamespace()
    {
        if (isset($_GET["s"])) {
            if (strpos($_GET['s'], '/') === 0) {
                $_GET['s'] = substr($_GET['s'], 1);
            }
            $appArray = explode("/", $_GET["s"]);
            for ($i = 2; $i < count($appArray); $i = $i + 2) {
                if (!empty($appArray[$i])) {
                    $_GET[urldecode($appArray[$i])]     = isset($appArray[$i + 1]) ? $appArray[$i + 1] : "";
                    $_REQUEST[urldecode($appArray[$i])] = isset($appArray[$i + 1]) ? $appArray[$i + 1] : "";
                }
            }
            unset($_GET["s"]);
            unset($_REQUEST["s"]);
        } else {
            $appArray = [];
        }
        $appArray[0] = (isset($appArray[0]) && !empty($appArray[0])) && preg_match('/^[a-zA-Z]{0,100}$/',
            $appArray[0]) == 1 ? $appArray[0] : "index";
        $appArray[1] = (isset($appArray[0]) && !empty($appArray[1])) && preg_match('/^[a-zA-Z0-9]{0,100}$/',
            $appArray[1]) == 1 ? $appArray[1] : "index";

        $controllerName = ucfirst(strtolower($appArray[0]));
        $class          = "\\" . MODEL_NAME . "\\Controller\\" . $controllerName . "Controller";
        $method         = strtolower($appArray[1]);
        if ((!class_exists($class)) || (!method_exists($class, $method))) {
            $class  = "\\" . MODEL_NAME . "\\Controller\\ErrorController";
            $method = "index";
        }
        self::defineSysConst($controllerName, $method);

        return ['class' => $class, 'method' => $method];
    }

    private function defineSysConst($controllerName, $actionName)
    {
        define("CONTROLLER_NAME", $controllerName);
        define("ACTION_NAME", $actionName);
        C('CACHE_PATH', CACHE_PATH);
    }
}